﻿using System;
using System.Linq;
using System.Net.Http;
using System.Threading;
using Common.Logging;
using In.Api.Dto.YBWs;
using Newtonsoft.Json;
using OutDbContext;
using Rmq.Center;
using User.Api.BizExtensions;
using User.Api.Helpers;
using User.Api.HttpClients;

namespace Out.TaskRunner.RmqWorkers
{
    public class OrderPayingTimeoutWorker : IWorker
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(OrderPayingTimeoutWorker));

        public void Start(CancellationToken ct)
        {
            if (ct.IsCancellationRequested)
            {
                return;
            }

            using (var consumer = new OrderPayingTimeoutConsumer())
            {
                consumer.Subscribe((id, count, dt, msg, channel) =>
                {
                    if (msg.OrderType == OrderType.挂号订单)
                    {
                        return ProcessRegOrder(msg.OrderId, channel);
                    }
                    else if (msg.OrderType == OrderType.门诊缴费订单)
                    {
                        //处理门诊缴费订单支付超时
                        return ProcessBillOrder(msg.OrderId, channel);
                    }
                    //else if (msg.OrderType == OrderType.住院预缴金订单)
                    //{
                    //    //处理预交金订单支付超时
                    //    return ProcessInpatientPrepayOrder(msg.OrderId, channel);
                    //}
    

                    return new ConsumedResult { Ack = true };
                });

                while (true)
                {
                    if (ct.IsCancellationRequested)
                    {
                        break;
                    }

                    Thread.Sleep(50);
                }
            }
        }

        private ConsumedResult ProcessRegOrder(int orderId, WrapperChannel channel)
        {
            OrderSummary order;
            using (var ctx = new GdsfybjyWeiXinEntities())
            {
                order = ctx.ApptOrders.IsStatus(ApptOrderExtensions.OrderStatus.支付中)
                    .Where(x => x.Id == orderId).Select(x => new OrderSummary
                    {
                        OrderStatus = x.OrderStatus,
                        OrderType = x.OrderType,
                        Id = x.Id
                    }).FirstOrDefault();
                if (order == null)
                {
                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }
            }
            DataBaseCommandFactory.CreateDatbaseCommand().UpdateOrderStatus(orderId, ApptOrderExtensions.OrderStatus.支付失败.ToInt32());

            //if (order.OrderType == ApptOrderExtensions.OrderType.预约.ToInt32().ToString())
            //{
                // RMQ 执行取消预约操作
                var unapptingProducer = new OrderUnapptingProducer();
                unapptingProducer.Publish(new OrderUnapptingMsg
                {
                    OrderType = Rmq.Center.OrderType.挂号订单,
                    OrderId = order.Id
                });
            //}


            return new ConsumedResult
            {
                Ack = true
            };
        }

        private ConsumedResult ProcessBillOrder(int orderId, WrapperChannel channel)
        {
            using (var ctx = new GdsfybjyWeiXinEntities())
            {
                var order = ctx.BillOrders.IsStatus(BillOrderExtensions.OrderStatus.支付中)
                    .FirstOrDefault(x => x.Id == orderId);
                if (order == null)
                {
                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }

                // 支付失败
                order.OrderStatus = BillOrderExtensions.OrderStatus.支付失败.ToInt32();
                ctx.SaveChanges();

                if (order.YiBaoStatus == BillOrderExtensions.YiBaoStatus.使用了医保.ToInt32()
                && !string.IsNullOrEmpty(order.YiBaoJydjh))
                {
                    order.YiBaoStatus = BillOrderExtensions.YiBaoStatus.取消医保中.ToInt32();
                    ctx.SaveChanges();

                    // 执行医保退费操作
                    var ybReturnRequest = new YBReturnChargesRequest();
                    ybReturnRequest.CardNo = order.CardNo;
                    ybReturnRequest.Jydjh = order.YiBaoJydjh;

                    YBReturnChargesResponse ybReturnResponse;
                    try
                    {
                        var httpClient = InHttpClient.GetClient();
                        var responseMsg = httpClient.PostAsJsonAsync("YBWs/YBReturnCharges", ybReturnRequest).Result;
                        responseMsg.EnsureSuccessStatusCode();
                        ybReturnResponse = responseMsg.Content.ReadAsAsync<YBReturnChargesResponse>().Result;
                    }
                    catch (Exception ex)
                    {
                        Logger.ErrorFormat("调用院内医保退费Api出错,信息：{0}", JsonConvert.SerializeObject(ex));

                        order.YiBaoStatus = BillOrderExtensions.YiBaoStatus.取消医保失败.ToInt32();
                        ctx.SaveChanges();

                        return new ConsumedResult
                        {
                            Ack = true
                        };
                    }

                    if (ybReturnResponse.ResultCode != "0")
                    {
                        order.YiBaoStatus = BillOrderExtensions.YiBaoStatus.取消医保失败.ToInt32();
                        ctx.SaveChanges();

                        return new ConsumedResult
                        {
                            Ack = true
                        };
                    }
                    else
                    {
                        order.YiBaoStatus = BillOrderExtensions.YiBaoStatus.取消了医保.ToInt32();
                        ctx.SaveChanges();

                        return new ConsumedResult
                        {
                            Ack = true
                        };
                    }
                }
            }

            return new ConsumedResult
            {
                Ack = true
            };
        }

        private ConsumedResult ProcessInpatientPrepayOrder(int orderId, WrapperChannel channel)
        {
            using (var ctx = new GdsfybjyWeiXinEntities())
            {
                var order = ctx.InpatientPrepayOrders.IsStatus(PrepayOrderExtensions.OrderStatus.支付中)
                    .FirstOrDefault(x => x.Id == orderId);
                if (order == null)
                {
                    return new ConsumedResult
                    {
                        Ack = true
                    };
                }

                // 支付失败
                order.OrderStatus = PrepayOrderExtensions.OrderStatus.支付失败.ToInt32();
                ctx.SaveChanges();
            }

            return new ConsumedResult
            {
                Ack = true
            };
        }

        public class OrderSummary
        {
            public int OrderStatus { get; set; }
            public string OrderType { get; set; }
            public int Id { get; set; }
        }
    }
}